<?php
require_once("Xiachufang/util/Mysql.php");
require_once("Xiachufang/util/MainConfig.php");

class DBMgr {
	static $connCache = array();
    static $config = array(
    "recipe"=>"main_db",
    "remark"=>"main_db",
    "actor"=>"main_db",
    "food"=>"main_db",
    "recipe_wiki"=>"main_db",
    "recipe_tag"=>"main_db",
    "favorite"=>"main_db",
    "event"=>"main_db",
    );
	
	static $useMaster = false;
	/**
	 * 强制使用master
	 */
	public static function forceMaster(){
		self::$useMaster = true;
	}
	/**
	 * get master mysql connection for table.
	 *
	 * @param string $table
	 * @return Mysql mysql
	 */
    public static function getMaster($table){
        if (isset(self::$config[$table])){
            $db = self::$config[$table];
            return self::_getDbMaster($db);
        } 
        Logger::getLogger("xiachufang")->fatal("没有设置表$table");
        return false;
    }

    /**
     * @return Mysql mysql
     */
    public static function getSlaver($table){
    	if (self::$useMaster){
    		return self::getMaster($table);
    	}
     	if (isset(self::$config[$table])){
            $db = self::$config[$table];
            return self::_getDbSlaver($db);
        }
		Logger::getLogger("xiachufang")->fatal("没有设置表$table");
		return false;
    }
	private static function _getDb($key,$newdb){
		$mysql = self::$connCache[$key];
		$mysql = new Mysql($mysql,$newdb);
		self::$connCache[$key] = $mysql;
		return $mysql;
	}
    private static function _getDbSlaver($db){
    	if (!MainConfig::getConfig("enable_slaver")){
    		return self::_getDbMaster($db);
    	}
        $connections = MainConfig::getConfig("connections");
        $connection = $connections[$db];
        if ($connection) {
           $masterKey = "masterconn_".$connection["host"].$connection["user"].$connection["pass"];
    	   //先检查master是否有连接，如果有则使用master的连接
 		   if (isset(self::$connCache[$masterKey])){
 		   		return self::_getDb($masterKey,$connection["database"]);
           }
           $slaverKey = "slaverconn_".$connection["host"].$connection["user"].$connection["pass"];
	       //检查此db的slaver连接是否存在
	       if (isset(self::$connCache[$slaverKey])){
	       		return self::_getDb($slaverKey,$connection["database"]);
	       }
	       	$slavers = $connection["slavers"];
	    	if ($slavers) {
		    	$count = count($slavers);
		        if (isset($_SERVER['REMOTE_ADDR'])) {
		            $ip = $_SERVER['REMOTE_ADDR'];
		        }
		        else {
		            $ip = "127.0.0.1";
		        }
		        $ipLong = ip2long($ip);
		         
		        $index = $ipLong*2654435761%$count;
		        $i = $index;
		        do {
		            $server = $slavers[$i];
		            if ($server['enable']) {
		                break;
		            }
		            $server = NULL;
		            $i = ($i+1)%$count;
		        }while($i!=$index);
		
	    	 	if ($server) {
		        	$mysql = Mysql::connect($server["host"],
			                		$server["user"],
			                		$server["pass"],
			                		$connection["database"]);
		            if (!$mysql){
		            	return false;
		            }
	            	self::$connCache[$slaverKey] = $mysql;
	            	return $mysql;
		        }
	    	}
        }
        return self::_getDbMaster($db);
    }
    
    private static function _getDbMaster($db){
        $connections = MainConfig::getConfig("connections");
        $connection = $connections[$db];
        if ($connection) {
        	$key = "masterconn_".$connection["host"].$connection["user"].$connection["pass"];
        	$mysqls = self::$connCache[$key];
	        if (!$mysqls){
	        	$mysql = Mysql::connect($connection["host"],
	                		$connection["user"],
	                		$connection["pass"],
	                		$connection["database"]);
	            if (!$mysql){
	            	return false;
	            }
	            self::$connCache[$key] = $mysql;
	            return $mysql;
	        } else {
	        	return self::_getDb($key,$connection["database"]);
	        }
        }
        return false;
    }
    //导入映射配置
    static function import($map){
    	foreach($map as $k =>$v) {
    		self::$config[$k]=$v;
    	}   
    } 
    
}

?>